package com.example.musicplayer.provider;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;

import androidx.annotation.NonNull;

import com.example.musicplayer.musicTools.LocalMusic;
import com.example.musicplayer.musicTools.UserTableManager;
import com.example.musicplayer.user.User;
import com.example.musicplayer.user.UserManage;

import java.util.List;

public class MusicContentProvider extends ContentProvider {
    private static final String AUTHORITY = "com.example.musicplayer.provider.MusicContentProvider";
    private static UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    private static DatabaseHelper mDatabaseHelper;

    //添加URI，在查询时进行匹配
    static {
        sMatcher.addURI(AUTHORITY, DBConstants.MusicDetail.TABLE_NAME, DBConstants.MusicDetail.URI_MATCH_CODE);
        sMatcher.addURI(AUTHORITY, DBConstants.User.TABLE_NAME, DBConstants.User.URI_MATCH_CODE);
    }

    //添加新建表的匹配码
    public static synchronized void addMatchCode(String tableName, int matchCode) {
        sMatcher.addURI(AUTHORITY, tableName, matchCode);
    }

    //重新分配匹配码
    public static synchronized void resetMatchCode(boolean includeUser) {
        sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sMatcher.addURI(AUTHORITY, DBConstants.MusicDetail.TABLE_NAME, DBConstants.MusicDetail.URI_MATCH_CODE);
        sMatcher.addURI(AUTHORITY, DBConstants.User.TABLE_NAME, DBConstants.User.URI_MATCH_CODE);
        if (includeUser) {
            String musicDetailUser = UserTableManager.getMusicDetailUserName();
            String musicMenuManage = UserTableManager.getMusicMenuManageName();
            if (musicDetailUser != null) {
                sMatcher.addURI(AUTHORITY, musicDetailUser, DBConstants.MusicDetailUser.URI_MATCH_CODE);
            }
            if (musicMenuManage != null) {
                sMatcher.addURI(AUTHORITY, musicMenuManage, DBConstants.MusicMenuManage.URI_MATCH_CODE);
            }
            List<String> tableName = UserTableManager.getTableName();
            List<Integer> matchCode = UserTableManager.getMatchCode();
            for (int i = 0; i < tableName.size(); i++) {
                sMatcher.addURI(AUTHORITY, tableName.get(i), matchCode.get(i));
            }
        }
    }

    //返回匹配得到的表名
    private static synchronized String matchUri(Uri uri) {
        int code = sMatcher.match(uri);
        if (code < 0) {
            return null;
        }
        if (code == DBConstants.MusicDetail.URI_MATCH_CODE) {
            return DBConstants.MusicDetail.TABLE_NAME;
        }
        if (code == DBConstants.User.URI_MATCH_CODE) {
            return DBConstants.User.TABLE_NAME;
        }
        return UserTableManager.getTableNameByMatchCode(code);
    }

    //create table music detail user
    public static boolean createMusicDetailUser(String tableName, int matchCode) {
        if (mDatabaseHelper == null) {
            return false;
        }
        addMatchCode(tableName, matchCode);
        if (mDatabaseHelper.createMusicDetailUser(tableName)) {
            return true;
        } else {
            resetMatchCode(false);
            return false;
        }
    }

    //create table music menu manage
    public static boolean createMusicMenuManage(String tableName, int matchCode) {
        if (mDatabaseHelper == null) {
            return false;
        }
        addMatchCode(tableName, matchCode);
        if (mDatabaseHelper.createMusicMenuManage(tableName)) {
            return true;
        } else {
            resetMatchCode(false);
            return false;
        }
    }

    //create table music menu detail
    public static boolean createMusicMenuDetail(String tableName, int matchCode) {
        if (mDatabaseHelper == null) {
            return false;
        }
        if (mDatabaseHelper.createMusicMenuDetail(tableName)) {
            addMatchCode(tableName, matchCode);
            return true;
        } else {
            return false;
        }
    }

    //delete table
    public static boolean deleteTable(String tableName) {
        if (mDatabaseHelper == null) {
            return false;
        }
        if (mDatabaseHelper.deleteTable(tableName)) {
            resetMatchCode(true);
            return true;
        } else {
            return false;
        }
    }

    public static void deleteUserData(String tableName) {
        User user = User.getInstance();
        if (user != null && user.hasAuthority() && mDatabaseHelper != null && tableName != null) {
            mDatabaseHelper.deleteTable(tableName);
        }
    }

    public static Cursor getUserData(String tableName, String[] projection, String selection, String[] selectionArgs
            , String sortOrder) {
        User user = User.getInstance();
        if (user != null && user.hasAuthority()) {
            return mDatabaseHelper.getWritableDatabase().query(tableName, projection, selection, selectionArgs
                    , null, null, null);
        }
        return null;
    }

    @Override
    public boolean onCreate() {
        if (mDatabaseHelper == null) {
            mDatabaseHelper = new DatabaseHelper(this.getContext());
        }
        return true;
    }

    @Override
    public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
        String tableName = matchUri(uri);
        if (tableName != null)
            return delete(tableName, selection, selectionArgs);
        return 0;
    }

    //执行删除操作
    private int delete(String tableName, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
        return db.delete(tableName, selection, selectionArgs);
    }

    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Override
    public Uri insert(@NonNull Uri uri, ContentValues values) {
        String tableName = matchUri(uri);
        if (tableName != null)
            return insert(tableName, uri, values);
        return uri;
    }

    //执行插入操作
    private Uri insert(String tableName, Uri uri, ContentValues values) {
        SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
        long id = db.insert(tableName, null, values);
        if (id > 0)
            uri = ContentUris.withAppendedId(uri, id);
        return uri;
    }

    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        String tableName = matchUri(uri);
        if (tableName != null)
            return query(tableName, projection, selection, selectionArgs, sortOrder);
        return null;
    }

    //执行查询操作
    private Cursor query(String tableName, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
        return db.query(tableName, projection, selection, selectionArgs, null, null, sortOrder);
    }

    @Override
    public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        String tableName = matchUri(uri);
        if (tableName != null)
            return update(tableName, values, selection, selectionArgs);
        return 0;
    }

    //执行更新操作
    private int update(String tableName, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
        return db.update(tableName, values, selection, selectionArgs);
    }

    public static class DatabaseHelper extends SQLiteOpenHelper {
        private static final String DB_NAME = "MusicPlayer.db";
        private static final int DB_VERSION = 1;

        private static final String SQL_CREATE_MUSIC_DETAIL = "create table " + DBConstants.MusicDetail.TABLE_NAME
                + " (" + DBConstants.MusicDetail.ID + " INTEGER primary key, "
                + DBConstants.MusicDetail.ALBUM_ID + " INTEGER, "
                + DBConstants.MusicDetail.SIZE + " INTEGER, "
                + DBConstants.MusicDetail.TITLE + " TEXT, "
                + DBConstants.MusicDetail.ALBUM + " TEXT, "
                + DBConstants.MusicDetail.ARTIST + " TEXT, "
                + DBConstants.MusicDetail.PATH + " TEXT, "
                + DBConstants.MusicDetail.LYRIC_PATH + " TEXT, "
                + DBConstants.MusicDetail.DATA_1 + " TEXT, "
                + DBConstants.MusicDetail.DATA_2 + " TEXT);";

        private static final String SQL_CREATE_USER = "create table " + DBConstants.User.TABLE_NAME
                + " (" + DBConstants.User.ID + " INTEGER primary key, "
                + DBConstants.User.NAME + " TEXT, "
                + DBConstants.User.PASSWORD + " TEXT, "
                + DBConstants.User.EMAIL + " TEXT, "
                + DBConstants.User.PHOTO + " INTEGER, "
                + DBConstants.User.VIP + " INTEGER, "
                + DBConstants.User.DATE + " TEXT, "
                + DBConstants.User.GRADE + " INTEGER, "
                + DBConstants.User.AUTHORITY + " INTEGER, "
                + DBConstants.User.DATA_1 + " TEXT, "
                + DBConstants.User.DATA_2 + " TEXT);";

        private static final String CREATE_TABLE_START = "create table ";
        private static final String DELETE_TABLE_START = "drop table ";

        private static final String CREATE_MUSIC_DETAIL_USER = " ("
                + DBConstants.MusicDetailUser.ID + " INTEGER primary key, "
                + DBConstants.MusicDetailUser.FAVORITE + " INTEGER, "
                + DBConstants.MusicDetailUser.LISTEN_COUNTS + " INTEGER, "
                + DBConstants.MusicDetailUser.AUTHORITY + " INTEGER, "
                + DBConstants.MusicDetailUser.DATA_1 + " TEXT, "
                + DBConstants.MusicDetailUser.DATA_2 + " TEXT);";

        private static final String CREATE_MUSIC_MENU_MANAGE = " ("
                + DBConstants.MusicMenuManage.NAME + " TEXT primary key, "
                + DBConstants.MusicMenuManage.MENU_ORDER + " INTEGER, "
                + DBConstants.MusicMenuManage.MENU_TABLE_NAME + " TEXT, "
                + DBConstants.MusicMenuManage.MATCH_CODE + " INTEGER, "
                + DBConstants.MusicMenuManage.INTRODUCTION + " TEXT, "
                + DBConstants.MusicMenuManage.BITMAP + " INTEGER, "
                + DBConstants.MusicMenuManage.LISTEN_COUNTS + " INTEGER, "
                + DBConstants.MusicMenuManage.MUSIC_SORT_TYPE + " TEXT, "
                + DBConstants.MusicMenuManage.DATA_1 + " TEXT, "
                + DBConstants.MusicMenuManage.DATA_2 + " TEXT);";

        private static final String CREATE_MUSIC_MENU_DETAIL = " ("
                + DBConstants.MusicMenuDetail.ID + " INTEGER primary key, "
                + DBConstants.MusicMenuDetail.MUSIC_ORDER + " INTEGER, "
                + DBConstants.MusicMenuDetail.DATA_1 + " TEXT, "
                + DBConstants.MusicMenuDetail.DATA_2 + " TEXT);";

        public DatabaseHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(SQL_CREATE_MUSIC_DETAIL);
            db.execSQL(SQL_CREATE_USER);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        }

        public boolean createMusicDetailUser(String tableName) {
            String sql = CREATE_TABLE_START + tableName + CREATE_MUSIC_DETAIL_USER;
            SQLiteDatabase db = getWritableDatabase();
            try {
                db.execSQL(sql);
                LocalMusic.initMusicDetailUser(tableName);
                return true;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
        }

        public boolean createMusicMenuManage(String tableName) {
            String sql = CREATE_TABLE_START + tableName + CREATE_MUSIC_MENU_MANAGE;
            SQLiteDatabase db = getWritableDatabase();
            try {
                db.execSQL(sql);
                return true;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
        }

        public boolean createMusicMenuDetail(String tableName) {
            String sql = CREATE_TABLE_START + tableName + CREATE_MUSIC_MENU_DETAIL;
            SQLiteDatabase db = getWritableDatabase();
            try {
                db.execSQL(sql);
                return true;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
        }

        public boolean deleteTable(String tableName) {
            if (tableName == null) {
                return false;
            }
            if (tableName.equals(DBConstants.MusicDetail.TABLE_NAME) || tableName.equals(DBConstants.User.TABLE_NAME)) {
                return false;
            }

            User user = User.getInstance();
            if (user == null) {
                return false;
            }

            if (tableName.startsWith(DBConstants.MusicDetailUser.TABLE_NAME)
                    || tableName.startsWith(DBConstants.MusicMenuManage.TABLE_NAME)) {
                if (!user.hasAuthority()) {
                    return false;
                } else {
                    return execDeleteTable(tableName);
                }
            }
            if (tableName.startsWith(DBConstants.MusicMenuDetail.TABLE_NAME)) {
                String[] strArray = tableName.split("_");
                int id = Integer.parseInt(strArray[3]);
                if (user.hasAuthority() || id == user.getUserId()) {
                    return execDeleteTable(tableName);
                }
            }
            return false;
        }

        private boolean execDeleteTable(String tableName) {
            String sql = DELETE_TABLE_START + tableName + ";";
            SQLiteDatabase db = getWritableDatabase();
            try {
                db.execSQL(sql);
                return true;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
        }
    }
}